﻿namespace UnityEngine
{
    using System;
    using System.Collections;
    using System.Runtime.CompilerServices;
    using UnityEngineInternal;

    public sealed class GameObject : UnityEngine.Object
    {
        public GameObject()
        {
            Internal_CreateGameObject(this, null);
        }

        public GameObject(string name)
        {
            Internal_CreateGameObject(this, name);
        }

        public GameObject(string name, params System.Type[] components)
        {
            Internal_CreateGameObject(this, name);
            foreach (System.Type type in components)
            {
                this.AddComponent(type);
            }
        }

        public T AddComponent<T>() where T: Component
        {
            return (this.AddComponent(typeof(T)) as T);
        }

        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        public extern Component AddComponent(string className);
        [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)]
        public Component AddComponent(System.Type componentType)
        {
            return this.Internal_AddComponentWithType(componentType);
        }

        public void BroadcastMessage(string methodName)
        {
            SendMessageOptions requireReceiver = SendMessageOptions.RequireReceiver;
            object parameter = null;
            this.BroadcastMessage(methodName, parameter, requireReceiver);
        }

        public void BroadcastMessage(string methodName, object parameter)
        {
            SendMessageOptions requireReceiver = SendMessageOptions.RequireReceiver;
            this.BroadcastMessage(methodName, parameter, requireReceiver);
        }

        public void BroadcastMessage(string methodName, SendMessageOptions options)
        {
            this.BroadcastMessage(methodName, null, options);
        }

        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        public extern void BroadcastMessage(string methodName, object parameter, SendMessageOptions options);
        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        public extern bool CompareTag(string tag);
        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        public static extern GameObject CreatePrimitive(PrimitiveType type);
        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        public static extern GameObject Find(string name);
        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        public static extern GameObject[] FindGameObjectsWithTag(string tag);
        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        public static extern GameObject FindGameObjectWithTag(string tag);
        public static GameObject FindWithTag(string tag)
        {
            return FindGameObjectWithTag(tag);
        }

        public T GetComponent<T>() where T: Component
        {
            return (this.GetComponent(typeof(T)) as T);
        }

        public Component GetComponent(string type)
        {
            return this.GetComponentByName(type);
        }

        [MethodImpl(MethodImplOptions.InternalCall), TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument), WrapperlessIcall]
        public extern Component GetComponent(System.Type type);
        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        private extern Component GetComponentByName(string type);
        public T GetComponentInChildren<T>() where T: Component
        {
            return (this.GetComponentInChildren(typeof(T)) as T);
        }

        [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)]
        public Component GetComponentInChildren(System.Type type)
        {
            if (this.activeInHierarchy)
            {
                Component component = this.GetComponent(type);
                if (component != null)
                {
                    return component;
                }
            }
            Transform transform = this.transform;
            if (transform != null)
            {
                IEnumerator enumerator = transform.GetEnumerator();
                try
                {
                    while (enumerator.MoveNext())
                    {
                        Transform current = (Transform) enumerator.Current;
                        Component componentInChildren = current.gameObject.GetComponentInChildren(type);
                        if (componentInChildren != null)
                        {
                            return componentInChildren;
                        }
                    }
                }
                finally
                {
                    IDisposable disposable = enumerator as IDisposable;
                    if (disposable == null)
                    {
                    }
                    disposable.Dispose();
                }
            }
            return null;
        }

        public T[] GetComponents<T>() where T: Component
        {
            return (T[]) this.GetComponentsInternal(typeof(T), true, false, true);
        }

        [CanConvertToFlash]
        public Component[] GetComponents(System.Type type)
        {
            return this.GetComponentsInternal(type, false, false, true);
        }

        public T[] GetComponentsInChildren<T>() where T: Component
        {
            return this.GetComponentsInChildren<T>(false);
        }

        public T[] GetComponentsInChildren<T>(bool includeInactive) where T: Component
        {
            return (T[]) this.GetComponentsInternal(typeof(T), true, true, includeInactive);
        }

        public Component[] GetComponentsInChildren(System.Type type)
        {
            bool includeInactive = false;
            return this.GetComponentsInChildren(type, includeInactive);
        }

        public Component[] GetComponentsInChildren(System.Type type, bool includeInactive)
        {
            return this.GetComponentsInternal(type, false, true, includeInactive);
        }

        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        private extern Component[] GetComponentsInternal(System.Type type, bool isGenericTypeArray, bool recursive, bool includeInactive);
        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        private extern Component Internal_AddComponentWithType(System.Type componentType);
        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        private static extern void Internal_CreateGameObject([Writable] GameObject mono, string name);
        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall, Obsolete("gameObject.PlayAnimation is not supported anymore. Use animation.Play")]
        public extern void PlayAnimation(AnimationClip animation);
        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        public extern void SampleAnimation(AnimationClip animation, float time);
        public void SendMessage(string methodName)
        {
            SendMessageOptions requireReceiver = SendMessageOptions.RequireReceiver;
            object obj2 = null;
            this.SendMessage(methodName, obj2, requireReceiver);
        }

        public void SendMessage(string methodName, object value)
        {
            SendMessageOptions requireReceiver = SendMessageOptions.RequireReceiver;
            this.SendMessage(methodName, value, requireReceiver);
        }

        public void SendMessage(string methodName, SendMessageOptions options)
        {
            this.SendMessage(methodName, null, options);
        }

        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        public extern void SendMessage(string methodName, object value, SendMessageOptions options);
        public void SendMessageUpwards(string methodName)
        {
            SendMessageOptions requireReceiver = SendMessageOptions.RequireReceiver;
            object obj2 = null;
            this.SendMessageUpwards(methodName, obj2, requireReceiver);
        }

        public void SendMessageUpwards(string methodName, object value)
        {
            SendMessageOptions requireReceiver = SendMessageOptions.RequireReceiver;
            this.SendMessageUpwards(methodName, value, requireReceiver);
        }

        public void SendMessageUpwards(string methodName, SendMessageOptions options)
        {
            this.SendMessageUpwards(methodName, null, options);
        }

        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        public extern void SendMessageUpwards(string methodName, object value, SendMessageOptions options);
        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]
        public extern void SetActive(bool value);
        [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall, Obsolete("gameObject.SetActiveRecursively() is obsolete. Use GameObject.SetActive(), which is now inherited by children.")]
        public extern void SetActiveRecursively(bool state);
        [MethodImpl(MethodImplOptions.InternalCall), Obsolete("gameObject.StopAnimation is not supported anymore. Use animation.Stop"), WrapperlessIcall]
        public extern void StopAnimation();

        [Obsolete("GameObject.active is obsolete. Use GameObject.SetActive(), GameObject.activeSelf or GameObject.activeInHierarchy.")]
        public bool active { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] set; }

        public bool activeInHierarchy { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public bool activeSelf { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public Animation animation { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public AudioSource audio { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public Camera camera { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public Collider collider { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public ConstantForce constantForce { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public GameObject gameObject
        {
            get
            {
                return this;
            }
        }

        [Obsolete("Please use guiTexture instead")]
        public GUIElement guiElement { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public GUIText guiText { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public GUITexture guiTexture { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public HingeJoint hingeJoint { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public bool isStatic { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] set; }

        internal bool isStaticBatchable { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public int layer { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] set; }

        public Light light { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public NetworkView networkView { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public ParticleEmitter particleEmitter { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public ParticleSystem particleSystem { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public UnityEngine.Renderer renderer { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public Rigidbody rigidbody { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }

        public string tag { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] set; }

        public Transform transform { [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall] get; }
    }
}

